﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Dynamic.Core;
using Microsoft.EntityFrameworkCore;
using PMS.SANY.Entity;
using Microsoft.Extensions.Logging;
using S7.Net;

namespace PMS.SANY.MonOrderServer.Siemens
{
    public sealed class SiemensHelper
    {
        public ILogger<Worker> _logger;
        private static SiemensHelper _instance = null;
        private static readonly object SynObject = new object();

        private Dictionary<string, int> order;
        /// <summary>
        /// 
        /// </summary>
        public List<string> WorkStationIds { set; get; }

        /// <summary>
        /// Gets the instance.
        /// </summary>
        public static SiemensHelper Instance
        {
            get
            {
                // Syn operation.
                lock (SynObject)
                {
                    return _instance ?? (_instance = new SiemensHelper());
                }
            }
        }

        SiemensHelper()
        {
            Writes = new Dictionary<string, SiemensWriter>();
            Readers = new Dictionary<string, SiemensReader>();
            order = new Dictionary<string, int>();

            using (var db = new GDbContextFactory().DbContext())
            {
                try
                {
                    var date = DateTime.Now.ToString("yyyyMMdd");
                    var reqId = "JBTHJXZK001" + date;
                    var seqNo = db.StationExecuted.Where(p => p.reqId.Contains(reqId)).Count();
                    order.Add(date, seqNo);
                }
                catch (Exception ex)
                {
                    _logger.LogError("AddStationExecuted Error:" + ex.Message);
                }
            }
        }

        public void InitWritesAndReaders()
        {
            Writes.Add("10.28.146.1", new SiemensWriter(CpuType.S71500, "10.28.146.1") { _logger = _logger });
            Readers.Add("10.28.146.1", new SiemensReader(CpuType.S71500, "10.28.146.1") { _logger = _logger });

            Writes.Add("10.28.146.2", new SiemensWriter(CpuType.S71500, "10.28.146.2") { _logger = _logger });
            Readers.Add("10.28.146.2", new SiemensReader(CpuType.S71500, "10.28.146.2") { _logger = _logger });

            Writes.Add("10.28.146.3", new SiemensWriter(CpuType.S71500, "10.28.146.3") { _logger = _logger });
            Readers.Add("10.28.146.3", new SiemensReader(CpuType.S71500, "10.28.146.3") { _logger = _logger });

            Writes.Add("10.28.146.4", new SiemensWriter(CpuType.S71500, "10.28.146.4") { _logger = _logger });
            Readers.Add("10.28.146.4", new SiemensReader(CpuType.S71500, "10.28.146.4") { _logger = _logger });

            Writes.Add("10.28.146.5", new SiemensWriter(CpuType.S71500, "10.28.146.5") { _logger = _logger });
            Readers.Add("10.28.146.5", new SiemensReader(CpuType.S71500, "10.28.146.5") { _logger = _logger });

            Writes.Add("10.28.146.6", new SiemensWriter(CpuType.S71500, "10.28.146.6") { _logger = _logger });
            Readers.Add("10.28.146.6", new SiemensReader(CpuType.S71500, "10.28.146.6") { _logger = _logger });

            Writes.Add("10.28.146.7", new SiemensWriter(CpuType.S71500, "10.28.146.7") { _logger = _logger });
            Readers.Add("10.28.146.7", new SiemensReader(CpuType.S71500, "10.28.146.7") { _logger = _logger });
        }

        private Dictionary<string, SiemensWriter> Writes { set; get; }

        private Dictionary<string, SiemensReader> Readers { set; get; }

        public bool Write(string ip, string address, VarType type, int count, object value)
        {
            try
            {
                return Writes[ip].WriteAsync(address, type, count, value).Result;
            }
            catch (Exception ex)
            {
                _logger.LogError("SiemensHelper.Write Error:" + address + " Msg:" + ex.Message);
            }
            return false;            
        }

        public void Regist(string ip, string address)
        {
            try
            {
                Readers[ip].Regist(address);
            }
            catch (Exception ex)
            {
                _logger.LogError("SiemensHelper.Regist Error:" + address + " Msg:" + ex.Message);
            }
        }

        public bool Read(string ip, string address)
        {
            try
            {
                return Readers[ip].Read(address);
            }
            catch(Exception ex)
            {
                _logger.LogError("SiemensHelper.Read Error:" + address + " Msg:" + ex.Message);
            }
            return false;
        }

        public int GetNextOrderId()
        {
            int result = 1;
            var date = DateTime.Now.ToString("yyyyMMdd");
            if (order.ContainsKey(date)) order[date] += 1;
            else order.Add(date, 1);
            result = order[date];

            var preDate = DateTime.Now.AddDays(-1).ToString("yyyyMMdd");
            if (order.ContainsKey(preDate)) order.Remove(preDate);

            return result;
        }
    }
}
